﻿// DialgWgMain.cpp: 实现文件
//
#include "pch.h"
#include "DialgWgMain.h"
#include "tinyxml2.h"
#include <string>



using namespace std;

// DialgWgMain 对话框

IMPLEMENT_DYNAMIC(DialgWgMain, CDialogEx)

DWORD dwBaseL1L2 = 0;




int DialgWgMain::mainRead() {
	using namespace tinyxml2;
	tinyxml2::XMLDocument doc;

	// 加载XML文件（注意路径中的反斜杠需要转义）
	if (doc.LoadFile("D:\\VSProjects\\wlwz\\npc.xml") != XML_SUCCESS) {
		std::cerr << "加载文件失败: " << doc.ErrorStr() << std::endl;
		return -1;
	}

	// 获取根节点
	XMLElement* root = doc.FirstChildElement("root");
	if (!root) {
		std::cerr << "找不到根节点 <root>" << std::endl;
		return -1;
	}

	std::vector<NpcData> npcList;

	// 遍历所有<npc>节点
	for (XMLElement* npc = root->FirstChildElement("npc");
		npc != nullptr;
		npc = npc->NextSiblingElement("npc"))
	{
		NpcData info;

		// 解析属性（带错误检查）
		if (npc->QueryIntAttribute("mapID", &info.mapID) != XML_SUCCESS) {
			std::cerr << "解析 mapID 失败" << std::endl;
			continue;
		}

		if (const char* id = npc->Attribute("npcID")) {
			info.npcID = id;
		}
		else {
			std::cerr << "解析 npcID 失败" << std::endl;
			continue;
		}

		if (npc->QueryIntAttribute("npcX", &info.npcX) != XML_SUCCESS) {
			std::cerr << "解析 npcX 失败" << std::endl;
			continue;
		}

		if (npc->QueryIntAttribute("npcY", &info.npcY) != XML_SUCCESS) {
			std::cerr << "解析 npcY 失败" << std::endl;
			continue;
		}

		npcList.push_back(info);
	}

	CString wsName=L"";
	

	// 输出解析结果
	for (const auto& npc : npcList) {
		std::cout << "地图ID: " << npc.mapID
			<< " NPC编号: " << npc.npcID
			<< " 坐标X: " << npc.npcX
			<< " 坐标Y: " << npc.npcY
			<< std::endl;
		CString t;
		t.Format(L"地图ID: %d , NPC编号 %s ,坐标X: %d ,坐标Y:%d \n", npc.mapID, npc.npcID, npc.npcX, npc.npcY);
		wsName = wsName+ t;
	}
	editShow->SetWindowTextW(wsName);
	return 0;
}

DialgWgMain::DialgWgMain(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG_WG_MAIN, pParent)
{
	__asm {
		mov	esi, GAME_BASE
		mov esi, [esi]
		mov	esi, [esi + GAME_BASE_P1]
		mov esi, [esi + GAME_BASE_P2]
		mov[dwBaseL1L2], esi
	}
}

DialgWgMain::~DialgWgMain()
{
}

BOOL DialgWgMain::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	editShow = GetDlgItem(IDC_EDIT_SHOW_ADRESS);
	editVIP = GetDlgItem(IDC_EDIT_VIP);
	svipChek = (CButton*)GetDlgItem(IDC_CHECK_SVIP);
	svipChek->SetCheck(BTNS_CHECK);
	setVipLevelData(30);
	return 0;
}

void DialgWgMain::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(DialgWgMain, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_DA_ZUO, &DialgWgMain::OnBnClickedButtonDaZuo)
	ON_BN_CLICKED(IDC_BUTTON_OPEN_NPC, &DialgWgMain::OnBnClickedButtonOpenNpc)
	ON_BN_CLICKED(IDC_BUTTON_FIND_CODE, &DialgWgMain::OnBnClickedButtonFindCode)
	ON_BN_CLICKED(IDC_BUTTON_LOGIN_XIAOZHANG, &DialgWgMain::OnBnClickedButtonLoginXiaozhang)
	ON_BN_CLICKED(IDC_BUTTONPSD, &DialgWgMain::OnBnClickedButtonpsd)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_CHECK_SVIP, &DialgWgMain::OnBnClickedCheckSvip)
	ON_BN_CLICKED(IDC_BUTTON_VIP_CHANGE, &DialgWgMain::OnBnClickedButtonVipChange)
	ON_BN_CLICKED(IDC_BUTTON_GOTO, &DialgWgMain::OnBnClickedButtonGoto)
	ON_BN_CLICKED(IDC_BUTTON_DLL, &DialgWgMain::OnBnClickedButtonDll)
	ON_BN_CLICKED(IDC_BUTTON_KILL_PID, &DialgWgMain::OnBnClickedButtonKillPid)
END_MESSAGE_MAP()



// DialgWgMain 消息处理程序


void DialgWgMain::OnBnClickedButtonDaZuo()
{
	_asm
	{
		pushad
		push 0x00040001
		mov ecx, [dwBaseL1L2]
		mov ebx, [GAME_CALL_REST]
		call ebx
		popad
	}
}

void go_to(PVOID pv, DWORD dwSize) {

	PDWORD pContext = reinterpret_cast<PDWORD>(pv);
	//-87, -44, true, QI_XIA
	DWORD x = pContext[1];
	DWORD y = pContext[2];
	DWORD bAuto = pContext[3];
	DWORD mapId = pContext[4];


	__asm {
		mov ecx, GAME_FIND_WAY_PIONT //Update
		mov eax, x
		mov[ecx], eax
		//mov [ecx +4],20
		mov eax, y
		mov[ecx + 8], eax  ///目的地坐标
		mov ecx, [dwBaseL1L2]
		lea ecx, [ecx + 0xb00]  // 当前人物坐标

		push mapId  // 地图
		push GAME_FIND_WAY_PIONT
		push ecx
		mov ecx, GAME_FIND_WAY_ECX
		call GAME_CALL_FIND_WAY
		//00530917.B9 A851E800   MOV ECX, elementc.00E851A8
		//0053091C.D95C24 48     FSTP DWORD PTR SS : [ESP + 48]
		//00530920.E8 CB44F0FF   CALL elementc.00434DF0;  寻路call
	}
}

bool GoToXY(FLOAT x, FLOAT y, BOOL bAuto, int mapId)
{
	DWORD array[] = {
		0,
		*((PDWORD)&x),
		*((PDWORD)&y),
		(DWORD)bAuto,
		(DWORD)mapId,
	};
	go_to(array, sizeof(array));
}


void DialgWgMain::OnBnClickedButtonOpenNpc()
{
	//mov ECX, 80003305 //NPC ID
	__asm {
		//mov ECX, 0x80003309 //NPC ID ,一线七侠镇 药师
		mov ECX, 0x8000331E //NPC ID ,九线七侠镇 药师
		mov EDX, GAME_BASE  //游戏基址
		mov EDX, [EDX]
		push ECX
		mov ECX, [EDX + 0x24]
		add ECX, 0x2A0
		call OPEN_PNC_DIALOG
	}
}


#define BLOCK_SIZE 50

void DialgWgMain::ScanAddress(HANDLE hProcess, const char* markCode, int distance, int findMode) {
	DWORD beginAddr = 0x00401000; // 开始地址，根据实际情况调整
	DWORD endAddr =   0x00500000; // 结束地址，根据实际情况调整
	DWORD pageSize = BLOCK_SIZE; // 每次读取的内存块大小
	BYTE page[BLOCK_SIZE]; // 用于读取内存块的缓冲区
	DWORD tmpAddr = 0x00CC6D65; // 当前读取地址
	CString str;
	CString strShow;
	SIZE_T* readByte = NULL;
	while (tmpAddr <= endAddr) {
		if (ReadProcessMemory(hProcess, (LPCVOID)(tmpAddr), page, BLOCK_SIZE, readByte)) { // 读取内存数据到缓冲区
			for (int i = 0; i < pageSize; i += distance) { // 在缓冲区中查找特征码，根据距离调整偏移量
				if (memcmp(&page[i], markCode, strlen(markCode)) == 0) { // 比较特征码是否匹配
					str.Format(L"Found at address: %o \n", tmpAddr + i);// 输出找到的特征码地址
					strShow = strShow + str;
					editShow->SetWindowTextW(strShow);
				// 输出找到的特征码地址
				}
				strShow.Format(L"Found at address: %s \n", page);
				editShow->SetWindowTextW(strShow);
			}
		}
		else { // 如果读取失败，则跳出循环并输出错误信息
			
			editShow->SetWindowTextW(L"Failed to read memory");
			break;
		}
		tmpAddr += pageSize; // 更新读取地址，继续遍历内存区域

	}
	if (strShow.IsEmpty()) {
		editShow->SetWindowTextW(L"strShow.IsEmpty()");
	}
}

void DialgWgMain::OnBnClickedButtonFindCode()
{
	HWND hWnd = (HWND)0x000C3C60;
	DWORD dwPID = NULL;
	GetWindowThreadProcessId(hWnd, &dwPID); 
	HANDLE hProcess = ::OpenProcess(PROCESS_VM_READ, false, dwPID);
	if (hProcess == NULL) {
		editShow->SetWindowTextW(L"Failed to open process");
		return ;
	}

	// 分配缓冲区
	int bufferSize = BLOCK_SIZE;
	LPVOID buffer = VirtualAlloc(NULL, bufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	if (buffer == NULL) {
		editShow->SetWindowTextW(L"Failed to allocate buffer");
		CloseHandle(hProcess);
		return ;
	}

	const char* markCode = "240150"; // 需要替换为实际特征码字符串
	int distance = 1; // 特征码与基址的距离，可以根据实际情况调整
	int findMode = 0; // 0表示向上查找，1表示向下查找

	// 执行内存扫描
	ScanAddress(GetCurrentProcess(), markCode, distance, findMode);
}


//void SimulateKeyPress(CString str) {
//	SimulateKeyPress(NULL, str);
//}

void SimulateKeyPress(CString str)
{
	// 遍历字符串中的每个字符
	for (int i = 0; i < str.GetLength(); ++i)
	{
		TCHAR ch = str[i];

		// 创建键盘输入事件
		KEYBDINPUT kb = { 0 };
		kb.wVk = VkKeyScan(ch);  // 获取虚拟键码
		kb.dwFlags = 0;          // 0表示按下键

		INPUT input = { 0 };
		input.type = INPUT_KEYBOARD;
		input.ki = kb;

		// 发送按下键盘事件
		//SendInput(1, &input, sizeof(INPUT));
		//::SendMessage(pWnd, WM_KEYDOWN, kb.wVk, 0);
		keybd_event(kb.wVk, 0, 0, 0);

		// 设置dwFlags以表示释放键
		kb.dwFlags = KEYEVENTF_KEYUP;
		input.ki = kb;

		// 发送释放键盘事件
		//SendInput(1, &input, sizeof(INPUT));
		//::SendMessage(pWnd, WM_KEYUP, kb.wVk, 0);
		keybd_event(kb.wVk, 0, KEYEVENTF_KEYUP, 0);
	}
}

void DialgWgMain::OnBnClickedButtonLoginXiaozhang()
{
	//CString name = _T("xintong2009sun");
	//SimulateKeyPress( name);

	//HWND hw = FindWindowA("QElementClient Window", "Element Client");
	//::ShowWindow(hw, SW_SHOW);
	//Sleep(3000);
	//
	////::SendMessage(hw, WM_KEYDOWN, VK_TAB, 0);
	////::SendMessage(hw, WM_KEYUP, VK_TAB, 0);
	//Sleep(300);
	//keybd_event(VK_TAB, 0, 0, 0);
	//// 模拟释放键
	//keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);
	//Sleep(300);

	SetTimer(1, 3000, NULL);

}


void DialgWgMain::OnBnClickedButtonpsd()
{
	CString pwd = _T("s15565380605");

	//// TODO: 在此添加控件通知处理程序代码
	//HWND hw = FindWindowA("QElementClient Window", "Element Client");
	SetTimer(2, 3000, NULL);
}


void DialgWgMain::OnTimer(UINT_PTR nIDEvent)
{
	if (nIDEvent == 1)
	{
		// 停止定时器
		KillTimer(1);

		// 执行你的延迟方法
	CString name = _T("xintong2009sun");
	SimulateKeyPress( name);
	}

	if (nIDEvent == 2)
	{
		// 停止定时器
		KillTimer(2);

		// 执行你的延迟方法
		CString pwd = _T("s15565380605");
		SimulateKeyPress(pwd);
	}

	CWnd::OnTimer(nIDEvent);
}

void DialgWgMain::OnBnClickedCheckSvip()
{
	if (svipChek->GetCheck() == BST_CHECKED) {
		setVipLevelData(30);
		return;
	}
	setVipLevelData(VIPRealLevel);
}

void DialgWgMain::setVipLevelData(int vipLevel)
{
	DWORD* pVIPRealLevel;
	__asm {
		mov	esi, GAME_BASE
		mov esi, [esi]
		mov	esi, [esi + GAME_BASE_P1]
		mov esi, [esi + GAME_BASE_P2]
		add esi, GAME_INFO_MAN_VIP_LEVEL
		mov pVIPRealLevel, esi
	}
	*pVIPRealLevel = (int)vipLevel;

	CString vipText;
	vipText.Format(L"%d", vipLevel);
	editVIP->SetWindowTextW(vipText);
}

void DialgWgMain::OnBnClickedButtonVipChange()
{
	CString vipText;
	editVIP->GetWindowTextW(vipText);
	int level = _ttoi(vipText);
	setVipLevelData(level);
}


void DialgWgMain::OnBnClickedButtonGoto()
{
	GoToXY(50,60,false,0x0A);

}

typedef const unsigned short* (__cdecl* GetNameFunc)(unsigned int);
typedef int(__cdecl* GetVersionFunc)(void);
typedef const char* (__cdecl* GetNativeNameFunc)(unsigned int);


void DialgWgMain::OnBnClickedButtonDll()
{
	//HINSTANCE hDll = LoadLibrary(L"E:\\武林外传\\element\\ElementSkill.dll");
	//if (hDll) {
	//	// 2. 获取函数地址（使用修饰后的名称）
	//	CString wsName;
	//	GetVersionFunc pGetVersion = (GetVersionFunc)GetProcAddress(hDll, "?GetVersion@ElementSkill@GNET@@SAHXZ");
	//	if (!pGetVersion) {
	//		wsName.Format(L"找不到函数！错误代码: %#x", GetLastError());
	//		editShow->SetWindowTextW(wsName);
	//		FreeLibrary(hDll);
	//		return ;
	//	}

	//	// 3. 调用函数
	//	int version = pGetVersion();
	//	wsName.Format(L"版本号:%d", version);
	//	editShow->SetWindowTextW(wsName);

	//	// 2. 获取函数地址（使用修饰后的名称）
	//	GetNativeNameFunc pGetNativeName = (GetNativeNameFunc)GetProcAddress(hDll, "?GetNativeName@ElementSkill@GNET@@SAPBDI@Z");
	//	if (!pGetNativeName) {
	//		wsName.Format(L"找不到函数！错误代码: %#x", GetLastError());
	//		editShow->SetWindowTextW(wsName);
	//		FreeLibrary(hDll);
	//		return ;
	//	}

	//	// 3. 调用函数并处理返回值
	//	unsigned int id = 123; // 示例参数
	//	const char* nativeName = pGetNativeName(1);
	//	if (nativeName) {
	//		wsName.Format(L"版本号:%d ，GetNativeName：", version, nativeName);
	//	
	//	}
	//	else {
	//		wsName.Format(L"找不到函数！GetNativeName: ");
	//	}
	//	editShow->SetWindowTextW(wsName);

	//	FreeLibrary(hDll);
	//}

	mainRead();

}



void DialgWgMain::OnBnClickedButtonKillPid()
{
	 // 1. 获取进程句柄（需要PROCESS_TERMINATE权限）
	HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, m_dwProcessId);
	if (hProcess == NULL)
	{
		// 获取错误信息
		DWORD dwError = GetLastError();
		CString strError;
		strError.Format(_T("无法打开进程！错误代码: %d"), dwError);
		AfxMessageBox(strError);
		return;
	}

	// 2. 终止进程
	BOOL bResult = TerminateProcess(hProcess, 0);  // 0为退出代码
	if (!bResult)
	{
		DWORD dwError = GetLastError();
		CString strError;
		strError.Format(_T("终止进程失败！错误代码: %d"), dwError);
		AfxMessageBox(strError);
	}

	// 3. 关闭句柄（必须）
	CloseHandle(hProcess);
}
